package com.ciccwm.auth.config.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

/**
 * 认证配置属性.
 */
@Data
@Validated
@ConfigurationProperties(prefix = "auth")
public class AuthProperties {
    
    /**
     * JWT配置
     */
    @NotNull
    private Jwt jwt = new Jwt();
    
    /**
     * Redis配置
     */
    @NotNull
    private Redis redis = new Redis();
    
    /**
     * 授权码配置
     */
    @NotNull
    private AuthCode authCode = new AuthCode();
    
    /**
     * 认证方式配置
     */
    @NotNull
    private Authentication authentication = new Authentication();
    
    /**
     * 访问令牌默认有效期（秒）.
     */
    private static final int DEFAULT_ACCESS_TOKEN_VALIDITY_SECONDS = 3600;
    
    /**
     * 刷新令牌默认有效期（秒）.
     */
    private static final int DEFAULT_REFRESH_TOKEN_VALIDITY_SECONDS = 86400;
    
    /**
     * 授权码默认有效期（秒）.
     */
    private static final int DEFAULT_CODE_VALIDITY_SECONDS = 60;
    
    /**
     * 验证码默认有效期（秒）.
     */
    private static final int DEFAULT_VERIFY_CODE_VALIDITY_SECONDS = 300;
    
    /**
     * 验证码默认长度.
     */
    private static final int DEFAULT_VERIFY_CODE_LENGTH = 6;
    
    /**
     * 密码最小长度.
     */
    private static final int DEFAULT_PASSWORD_MIN_LENGTH = 8;
    
    /**
     * 密码最大长度.
     */
    private static final int DEFAULT_PASSWORD_MAX_LENGTH = 32;
    
    /**
     * 限流默认周期（秒）.
     */
    private static final int DEFAULT_RATE_LIMIT_PERIOD = 60;
    
    /**
     * 限流默认次数.
     */
    private static final int DEFAULT_RATE_LIMIT_COUNT = 1000;
    
    /**
     * 重试限制默认周期（秒）.
     */
    private static final int DEFAULT_RETRY_LIMIT_PERIOD = 300;
    
    /**
     * 重试限制默认次数.
     */
    private static final int DEFAULT_RETRY_LIMIT_COUNT = 5;
    
    /**
     * 默认锁定时长（秒）.
     */
    private static final int DEFAULT_LOCK_DURATION = 600;
    
    /**
     * 验证码默认长度.
     */
    private static final int DEFAULT_CAPTCHA_LENGTH = 4;
    
    /**
     * 验证码默认过期时间（秒）.
     */
    private static final int DEFAULT_CAPTCHA_EXPIRE_SECONDS = 60;
    
    /**
     * 验证码图片默认宽度.
     */
    private static final int DEFAULT_CAPTCHA_WIDTH = 120;
    
    /**
     * 验证码图片默认高度.
     */
    private static final int DEFAULT_CAPTCHA_HEIGHT = 40;
    
    /**
     * 验证码默认干扰线数量.
     */
    private static final int DEFAULT_CAPTCHA_LINE_COUNT = 30;
    
    /**
     * 密码历史记录默认大小.
     */
    private static final int DEFAULT_PASSWORD_HISTORY_SIZE = 16;
    
    /**
     * 密码默认过期天数.
     */
    private static final int DEFAULT_PASSWORD_EXPIRE_DAYS = 32;

    /**
     * 访问令牌有效期（秒）.
     */
    private int accessTokenValiditySeconds = DEFAULT_ACCESS_TOKEN_VALIDITY_SECONDS;

    /**
     * 刷新令牌有效期（秒）.
     */
    private int refreshTokenValiditySeconds = DEFAULT_REFRESH_TOKEN_VALIDITY_SECONDS;

    /**
     * 授权码有效期（秒）.
     */
    private int codeValiditySeconds = DEFAULT_CODE_VALIDITY_SECONDS;

    /**
     * 验证码有效期（秒）.
     */
    private int verifyCodeValiditySeconds = DEFAULT_VERIFY_CODE_VALIDITY_SECONDS;

    /**
     * 验证码长度.
     */
    private int verifyCodeLength = DEFAULT_VERIFY_CODE_LENGTH;

    /**
     * 密码最小长度.
     */
    private int passwordMinLength = DEFAULT_PASSWORD_MIN_LENGTH;

    /**
     * 密码最大长度.
     */
    private int passwordMaxLength = DEFAULT_PASSWORD_MAX_LENGTH;

    /**
     * 限流周期（秒）.
     */
    private int rateLimitPeriod = DEFAULT_RATE_LIMIT_PERIOD;

    /**
     * 限流次数.
     */
    private int rateLimitCount = DEFAULT_RATE_LIMIT_COUNT;

    /**
     * 重试限制周期（秒）.
     */
    private int retryLimitPeriod = DEFAULT_RETRY_LIMIT_PERIOD;

    /**
     * 重试限制次数.
     */
    private int retryLimitCount = DEFAULT_RETRY_LIMIT_COUNT;

    /**
     * 锁定时长（秒）.
     */
    private int lockDuration = DEFAULT_LOCK_DURATION;

    /**
     * 验证码长度.
     */
    private int captchaLength = DEFAULT_CAPTCHA_LENGTH;

    /**
     * 验证码过期时间（秒）.
     */
    private int captchaExpireSeconds = DEFAULT_CAPTCHA_EXPIRE_SECONDS;

    /**
     * 验证码图片宽度.
     */
    private int captchaWidth = DEFAULT_CAPTCHA_WIDTH;

    /**
     * 验证码图片高度.
     */
    private int captchaHeight = DEFAULT_CAPTCHA_HEIGHT;

    /**
     * 验证码干扰线数量.
     */
    private int captchaLineCount = DEFAULT_CAPTCHA_LINE_COUNT;

    /**
     * 密码历史记录大小.
     */
    private int passwordHistorySize = DEFAULT_PASSWORD_HISTORY_SIZE;

    /**
     * 密码过期天数.
     */
    private int passwordExpireDays = DEFAULT_PASSWORD_EXPIRE_DAYS;

    /**
     * JWT配置类.
     * 包含JWT密钥、签发者和受众等配置.
     */
    @Data
    public static class Jwt {
        /**
         * JWT密钥.
         * 用于签名和验证JWT令牌.
         */
        @NotBlank
        private String secret = "your-secret-key";
        
        /**
         * 令牌签发者.
         * 用于标识JWT令牌的签发者.
         */
        private String issuer = "auth-service";
        
        /**
         * 令牌受众.
         * 用于标识JWT令牌的目标受众.
         */
        private String audience = "api-clients";
    }
    
    /**
     * Redis配置类.
     * 包含Redis启用状态、本地缓存配置等.
     */
    @Data
    public static class Redis {
        /**
         * 是否启用Redis.
         * 如果为false则使用内存缓存.
         */
        private boolean enabled = true;
        
        /**
         * 本地缓存大小.
         * 指定本地缓存最大条目数.
         */
        @Min(100)
        private int localCacheSize = 1000;
        
        /**
         * 本地缓存过期时间（秒）.
         * 指定本地缓存条目的过期时间.
         */
        @Min(60)
        private long localCacheExpiration = 600;
        
        /**
         * 缓存键前缀.
         * 用于区分不同类型的缓存数据.
         */
        private String keyPrefix = "auth:";
    }
    
    /**
     * 授权码配置类.
     * 包含授权码长度和字符集等配置.
     */
    @Data
    public static class AuthCode {
        /**
         * 授权码长度.
         * 指定生成的授权码字符串长度.
         */
        @Min(16)
        private int length = 32;
        
        /**
         * 授权码字符集.
         * 用于生成授权码的字符集合.
         */
        private String charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    }
    
    /**
     * 认证配置类.
     * 包含密码加密、多因素认证和账户锁定等配置.
     */
    @Data
    public static class Authentication {
        /**
         * 密码加密算法.
         * 支持的算法包括：bcrypt、pbkdf2、scrypt等.
         */
        private String passwordEncoder = "bcrypt";
        
        /**
         * 密码加密强度.
         * bcrypt算法的工作因子，值越大加密强度越高.
         */
        @Min(4)
        private int passwordStrength = 10;
        
        /**
         * 是否启用多因素认证.
         * 如果启用，用户需要提供额外的验证因素.
         */
        private boolean mfaEnabled = false;
        
        /**
         * 登录失败最大尝试次数.
         * 超过此次数账户将被锁定.
         */
        @Min(3)
        private int maxLoginAttempts = 5;
        
        /**
         * 账户锁定时间（分钟）.
         * 账户被锁定后的解锁等待时间.
         */
        @Min(5)
        private int accountLockTime = 30;
    }
} 
